﻿using System;
// 多播委托
// 所有的委托实例都有多播能力。
// 意思是一个委托实例不仅可以引用一个目标方法，而且可以引用一组目标方法。
// 用运算符+和+=联合多个委托实例。
//SomeDelegate d = SomeMethod1;
//d+=SomeMethod2;
//后一句等同于：
//d = d + SomeMethod2;
//现在调用d不仅会调用SomeMethod1，而且会调用SomeMethod2。委托按照添加的顺序依次被触发。
// 运算符-和-=从左边的委托操作数中移除右边的委托操作数。
//d -= SomeMethod1;
//现在调用d只能触发SomeMethod2。
//SomeDelegate d = null;
//d += SomeMethod1; // 当d式null值时等价于d = SomeMethod1;
//同样，在只有唯一目标方法的委托上调用-=等于为该变量指定null值。
// 提示：委托式不可变的，因此调用+=或-=的实质是创建一个新的委托实例，并把它赋值给已有变量。
// 如果多播委托有非void的返回类型，调用者从最后一个触发的方法接受返回值。前面的方法仍然被调用，但返回值都被丢弃了。大部分情况下调用的多播委托都是返回void类型，所以这个细小的差别就没有了。

namespace _082_多播委托
{
    // 多播委托的实例
    //假如写了一个需要运行很长时间的例程，该例程通过调用委托向它的调用者报告进程执行情况。
    //在本例中，例程HardWork有一个ProgressReporter委托参数，例程调用该参数指明进程运行情况：
    public delegate void ProgressReporter(int percentComplete);

    public class Util
    {
        public static void HardWork(ProgressReporter p)
        {
            for (int i = 0; i < 10; i++)
            {
                p(i * 10); // 调用委托
                System.Threading.Thread.Sleep(100); // 模拟长时间运行
            }
        }
    }
    //为了监视执行进度，在Main方法中创建一个多播委托实例p，这样通过两个独立的方法监视执行进度：
    class Test
    {
        static void WriteProgressToConsole(int percentComplete)
        {
            Console.WriteLine(percentComplete);
        }
        static void WriteProgressToFile(int percentComplete)
        {
            System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
        }
        static void Main(string[] args)
        {
            ProgressReporter p = WriteProgressToConsole;
            p += WriteProgressToFile;
            Util.HardWork(p);

            Console.ReadKey();
        }
    }
}